package com.travel.server.manager.impl.command.order;

import com.travel.common.CommonConstant;
import com.travel.common.exception.WorkCode;
import com.travel.common.exception.WorkException;
import com.travel.common.util.CollectionUtil;
import com.travel.common.util.CommonUtil;
import com.travel.server.manager.dto.request.order.RefundOrderRequest;
import com.travel.server.manager.dto.response.order.RefundOrderResponse;
import com.travel.server.manager.impl.command.AbstractCommand;
import com.travel.server.manager.impl.dal.OrderDal;
import com.travel.server.manager.impl.dal.RefundDal;
import com.travel.server.manager.impl.dal.RefundDal.OrderRefundParam;
import com.travel.server.manager.impl.enums.OrderRefundEnum;
import com.travel.server.manager.impl.enums.OrderStateEnum;
import com.travel.server.manager.impl.enums.OrderStepEnum;
import com.travel.server.manager.impl.sal.OrderSal;
import com.travel.server.manager.impl.sal.RefundSal;
import com.travel.server.manager.model.OrderInfo;
import com.travel.server.manager.model.OrderRefundInfo;
import com.travel.server.manager.model.UserInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * @Author: LiZhenhui
 * @Date: 2018/11/5 18:20
 * @Desc:
 */
@Component
@Slf4j
public class RefundOrderCommand extends AbstractCommand<RefundOrderRequest, RefundOrderResponse> {

    @Autowired
    private OrderDal orderDal;

    @Autowired
    private RefundDal refundDal;

    @Override
    protected void checkInput(RefundOrderRequest request) {
        if(request.getId() == null || StringUtils.isBlank(request.getRefundState()) || request.getRefundAmount() == null){
            throwInvalidParam();
        }
    }

    @Override
    public RefundOrderResponse handle(RefundOrderRequest request) {
        checkInput(request);

        UserInfo userInfo = getUserInfo();

        Integer id = request.getId();
        OrderInfo orderInfo = orderDal.selectById(id);

        //判断订单是否有赞订单，是则调用有赞API
        if(CommonConstant.YES.equals(orderInfo.getOrderMark())){
            throw new WorkException(WorkCode.REFUND_UN_PERMISSION);
        }else {
            String refundId = request.getRefundId();
            if(StringUtils.isBlank(refundId)){
                refundId = RefundSal.getNewRefundId();
                request.setRefundId(refundId);
            }
            OrderRefundParam param = new OrderRefundParam();
            param.setRefundId(refundId);
            if (!CollectionUtil.isEmpty(refundDal.selectByExample(param))) {
                log.error("已存在相同流水号的记录, refundId {}", refundId);
                throw new WorkException(WorkCode.EXIT_SAME_REFUND_ID);
            }
        }

        Integer refundId = makeRefund(orderInfo, request, userInfo);

        RefundOrderResponse response = new RefundOrderResponse();
        response.setId(refundId);
        return response;
    }

    public Integer makeRefund(OrderInfo orderInfo, RefundOrderRequest request, UserInfo userInfo){
        Date now = new Date();

        if(!request.getRefundState().equals(OrderStateEnum.REFUND_ING.getState()) && !request.getRefundState().equals(OrderStateEnum.REFUND_SUCCESS.getState())){
            throw new WorkException(WorkCode.REFUND_STATE_ERROR);
        }
        orderInfo.setOrderState(request.getRefundState());
        orderInfo.setOrderStep(OrderStepEnum.ORDER_REFUND.getStep());
        if(request.getRefundState().equals(OrderStateEnum.REFUND_ING.getState())) {
            orderInfo.setRefundState(OrderRefundEnum.AGREE.getState());
        }else{
            orderInfo.setRefundState(OrderRefundEnum.SUCCESS.getState());
        }
        orderInfo.setUpdateBy(userInfo.getName());
        orderInfo.setUpdateTime(now);
        orderInfo.setNote(OrderSal.getNewNote(orderInfo.getNote(), request.getNote()));
        orderDal.insertOrUpdate(orderInfo);

        OrderRefundInfo orderRefundInfo = refundDal.selectByOrderId(orderInfo.getId());
        if(orderRefundInfo == null) {
            orderRefundInfo = new OrderRefundInfo();
            orderRefundInfo.setCreateTime(now);
            orderRefundInfo.setCreateBy(userInfo.getName());
            orderRefundInfo.setRefundReason(request.getNote());
            orderRefundInfo.setOrderId(orderInfo.getId());
            if(OrderRefundEnum.SUCCESS.getState().equals(orderInfo.getRefundState())){
                orderRefundInfo.setRefundSuccessTime(now);
            }
        }
        orderRefundInfo.setRefundReason(OrderSal.getNewNote(orderRefundInfo.getRefundReason(), request.getNote()));
        orderRefundInfo.setRefundId(request.getRefundId());
        orderRefundInfo.setRefundAmount(CommonUtil.yuanToFen(request.getRefundAmount()).longValue());
        orderRefundInfo.setUpdateTime(now);
        orderRefundInfo.setUpdateBy(userInfo.getName());

        return refundDal.insertOrUpdate(orderRefundInfo);
    }
}
